#include "EpilObjectHelper.h"
#include "EpilBooleanObject.h"
#include <limits>

using namespace std;


tstring EpilObjectHelper::ToString( bool value )
{
	return value ? t("true") : t("false");
}


tstring EpilObjectHelper::ToString( int value )
{
	tstringstream ret;
	ret << value;
	return ret.str();
}


tstring EpilObjectHelper::ToString( double value )
{
	tstringstream ret;
	ret << value;
	return ret.str();
}


bool EpilObjectHelper::IsDoubleEquals( double lhs, double rhs )
{
	return fabs( lhs - rhs ) < numeric_limits<double>::epsilon();
}


bool EpilObjectHelper::IsDoubleLessThanOrEquals( double lhs, double rhs )
{
	return EpilObjectHelper::IsDoubleEquals( lhs, rhs ) || lhs < rhs;
}


bool EpilObjectHelper::IsDoubleGreaterThanOrEquals( double lhs, double rhs )
{
	return EpilObjectHelper::IsDoubleEquals( lhs, rhs ) || lhs > rhs;
}


bool EpilObjectHelper::IsInteger( double value )
{
	if( IsDoubleEquals( GetDoubleMod( value, static_cast<int>( value ) ), 0 ) )
	{
		return true;
	}
	return false;
}


double EpilObjectHelper::GetDoubleMod( double lhs, double rhs )
{
	int divResult = static_cast<int>( lhs / rhs );
	return lhs - rhs * divResult;
}


bool EpilObjectHelper::IsArithmeticOperator( EpilBinaryOperator op )
{
	switch( op )
	{
	case EBO_Add:
	case EBO_Minus:
	case EBO_Multiply:
	case EBO_Divide:
	case EBO_Mod:
	case EBO_Power:
		return true;
	default:
		return false;
	}
}


bool EpilObjectHelper::IsLogicOperator( EpilBinaryOperator op )
{
	switch( op )
	{
	case EBO_And:
	case EBO_Or:
		return true;
	default:
		return false;
	}
}


bool EpilObjectHelper::IsComparisonOperator( EpilBinaryOperator op )
{
	switch( op )
	{
	case EBO_Equal:
	case EBO_GreaterThan:
	case EBO_GreaterThanOrEqual:
	case EBO_LessThan:
	case EBO_LessThanOrEqual:
	case EBO_Unequal:
		return true;
	default:
		return false;
	}
}


bool EpilObjectHelper::IsConditionTrue( const EpilObject * obj )
{
	if( obj->GetType() == EOT_Nil )
	{
		return false;
	}

	if( obj->GetType() == EOT_Boolean )
	{
		const EpilBooleanObject * boolObj = static_cast<const EpilBooleanObject *>( obj );
		return boolObj->GetValue();
	}

	return true;
}